# define other functions
# 
# Author: guochun
###############################################################################



#select a random transect line with minimun distance
transectLine=function(distanceOBJ,populationData){
	allx=seq(0,populationData@plotdim[1],0.1)
	ally=seq(0,populationData@plotdim[2],0.1)
	dmax=sqrt((populationData@plotdim[1])^2+(populationData@plotdim[2])^2)
	
	while(length(distanceOBJ@d)==0 || distanceOBJ@d<dmax/5 ||
			(distanceOBJ@xrange[2]-distanceOBJ@xrange[1]) < 2*distanceOBJ@edge ){
		x=sample(allx,2)
		y=sample(ally,2)
		slope=(y[2]-y[1])/(x[2]-x[1])
		b=y[1]-slope*x[1]
		distanceOBJ@slope=slope
		distanceOBJ@b=b
		distanceOBJ@xrange=c(0,populationData@plotdim[1])
		xmax=-b/slope
		xmin=(populationData@plotdim[2]-b)/slope
		if(slope<0){
			if(xmax < populationData@plotdim[1])
				distanceOBJ@xrange[2]=xmax
			if(xmin > 0)
				distanceOBJ@xrange[1]=xmin
		}else if(slope >0 ){
			if(xmax>0)
				distanceOBJ@xrange[1]=xmax
			if(xmin < populationData@plotdim[1])
				distanceOBJ@xrange[2]=xmin
		}
		d=sqrt((distanceOBJ@xrange[1]-distanceOBJ@xrange[2])^2+(selectionLine(distanceOBJ@xrange[1],slope,b)-selectionLine(distanceOBJ@xrange[2],slope,b))^2)
		distanceOBJ@d=d
		if(is.nan(d))
			browser()
		#print(d)
	}
	return(distanceOBJ)
}

selectionLine=function(x,tgbeta,b){
	return(x*tgbeta+b)
}



randomPointSample=function(a,b,xs,ys,dimx,dimy){
	x=sample(seq(0,dimx-a,by=1),1)
	y=sample(seq(0,dimy-b,by=1),1)
	availible=which(xs >= x & xs <= x+a & ys >= y & ys <= y+b)
	attr(availible,"point")=c(x,y)
	return(availible)
}


setSampleResultForquadrat=function(sampleOBJ,selection,populationData){
	sample=new("population",x=populationData@x[selection],y=populationData@y[selection],plotdim=populationData@plotdim)
	border=attr(selection,"point")
	
	attr(sample,"border")=c(border[1],border[1]+sampleOBJ@a,border[2],border[2]+sampleOBJ@b)
	populationData@samples=c(populationData@samples,sample)
	return(populationData)
}

appendResult=function(sampleOBJ,selection,populationData){
	ns=length(populationData@samples)
	populationData@samples[[ns+1]]=attr(selection,"d")
	return(populationData)
}

plot.rectangle=function(quadratOBJ,populationData){
	plotForQuadrat(populationData)
}

plot.circle=function(quadratOBJ,populationData){
	plotForQuadrat(populationData)
}

plot.eToe=function(quadratOBJ,populationData){
	plotForDistance(populationData)
}
plot.pToe=function(quadratOBJ,populationData){
	plotForDistance(populationData)
}

plot.tSquare=function(quadratOBJ,populationData){
	plot(x=populationData@x,y=populationData@y,cex=0.4)
	for(i in 1:length(populationData@samples)){
		samplePair=as.numeric(populationData@samples[[i]])
		points(x=samplePair[1],y=samplePair[2],col=2,pch=19)
		points(x=samplePair[3],y=samplePair[4],col=3,pch=19)
		points(x=samplePair[5],y=samplePair[6],col=3,pch=19)
		segments(samplePair[1],samplePair[2],samplePair[3],samplePair[4])
		segments(samplePair[3],samplePair[4],samplePair[5],samplePair[6],col=2)
	}
}

plot.pQuarter=function(quadratOBJ,populationData){
	plot(x=populationData@x,y=populationData@y,cex=0.4)
	abline(quadratOBJ@b,quadratOBJ@slope)
	for(i in 1:length(populationData@samples)){
		samplePair=as.numeric(populationData@samples[[i]])
		points(x=samplePair[1],y=samplePair[2],pch=19)
		points(x=samplePair[3],y=samplePair[4],pch=19,col=2)
		points(x=samplePair[6],y=samplePair[7],pch=19,col=2)
		points(x=samplePair[9],y=samplePair[10],pch=19,col=2)
		points(x=samplePair[12],y=samplePair[13],pch=19,col=2)
		segments(x0=samplePair[1],y0=samplePair[2],x1=samplePair[3],y1=samplePair[4])
		segments(x0=samplePair[1],y0=samplePair[2],x1=samplePair[6],y1=samplePair[7])
		segments(x0=samplePair[1],y0=samplePair[2],x1=samplePair[9],y1=samplePair[10])
		segments(x0=samplePair[1],y0=samplePair[2],x1=samplePair[12],y1=samplePair[13])
	}
}


plotForDistance=function(populationData){
	plot(x=populationData@x,y=populationData@y,cex=0.6,xlab="x",ylab="y")
	startpp=as.numeric(populationData@samples[[1]])
	if(any(populationData@x == startpp[1]) & any(populationData@y == startpp[2]))
		pch=19
	else
		pch=3
	for(i in 1:length(populationData@samples)){
		samplePair=as.numeric(populationData@samples[[i]])
		points(x=samplePair[1],y=samplePair[2],col=2,pch=pch,cex=0.6)
		#points(x=samplePair[3],y=samplePair[4],col=3,pch=19)
		segments(samplePair[1],samplePair[2],samplePair[3],samplePair[4])
	}
}

plotForQuadrat=function(populationData){
	plot(x=populationData@x,y=populationData@y,cex=0.4,xlab="x",ylab="y")
	for(i in 1:length(populationData@samples)){
		subpopulation=populationData@samples[[i]]
		#browser()
		border=attr(subpopulation,"border")
		lines(x=c(border[1],border[2],border[2],border[1],border[1]),y=c(border[3],border[3],border[4],border[4],border[3]))
		
		points(x=subpopulation@x,y=subpopulation@y,pch=19,col=2,cex=0.7)
	}
	
}

borderEdgeCorrection=function(population, edge){
	population@availible=which(population@x >= edge & population@x <= (population@plotdim[1]-edge) & population@y >= edge & population@y <= (population@plotdim[2]-edge))
	return(population)
}


isReachLimit=function(i,quadratOBJ){
	quadratOBJ@success= (i>quadratOBJ@stopLimit)
	return(quadratOBJ)
}

setSampledPoints=function(selection,populationData){
	if(length(populationData@sampled)==1)
		populationData@sampled=rep(F,length(populationData@x))
	
	populationData@sampled[selection]=T
	return(populationData)
}

setSampleArea=function(availiable,populationData){
	border=attr(availiable,"point")
	sampledArea=attr(populationData,"sampledArea")
	if(is.null(sampledArea)){
		sampledArea=matrix(border,nrow=1,ncol=2)
	}else{
		sampledArea=rbind(sampledArea,border)
	}
    attr(populationData,"sampledArea")=sampledArea
	return(populationData)
}

isAreaOverlaped=function(availiable,populationData,sampleMethod){
	border=attr(availiable,"point")
	border=expand.grid(x=c(border[1],border[1]+sampleMethod@a),y=c(border[2],border[2]+sampleMethod@b))
	sampledArea=attr(populationData,"sampledArea")
	if(is.null(sampledArea))
		return(FALSE)
	for(i in 1:4){
		tp=as.numeric(border[i,])
		if(i ==1){
			overlap=tp[1]>=sampledArea[,1] & tp[1]<= (sampledArea[,1] + sampleMethod@a) & 
					tp[2]>=sampledArea[,2] & tp[2]<= (sampledArea[,2] + sampleMethod@b)
		}else{
			overlap=(tp[1]>=sampledArea[,1] & tp[1]<= (sampledArea[,1] + sampleMethod@a) & 
					tp[2]>=sampledArea[,2] & tp[2]<= (sampledArea[,2] + sampleMethod@b) ) | overlap
		}
	}
	return(any(overlap))
	
}


